﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using Oracle.DataAccess.Client;

namespace Petaframe.DataAccess
{
    /// <summary>
    /// Oracle veritabanına ait işlemler için parametrelere ait bilgileri oluşturur.
    /// </summary>
    internal class OracleParameterBuilder : IParameterBuilder
    {

     //   DbProviderFactory _providerFactory;
        //public OracleParameterBuilder()
        //{
        //    _providerFactory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
        //}


        public ParameterInfo CreateParameter(DbProviderFactory factory, int index, System.Reflection.PropertyInfo clazzProperty) 
        {
            ParameterInfo pInfo = new ParameterInfo();

            var uniqueName = Guid.NewGuid().ToString().Substring(0, 7);
            pInfo.ParameterSimpleName="p"+index;
            pInfo.ParameterUniqueName = "p" + uniqueName;
            pInfo.ParameterColumnName=clazzProperty.Name;
            pInfo.ParameterPosition=index;

            var oraParameter= factory.CreateParameter() as OracleParameter;
            oraParameter.ParameterName = ":p" + index;

            //value tip mi?
            if (clazzProperty.PropertyType.IsValueType)
            {
                //Nullable tip mi?
                if (clazzProperty.PropertyType.IsGenericType)
                    oraParameter.OracleDbType = TypeToDbType(Nullable.GetUnderlyingType(clazzProperty.PropertyType).Name);
                else
                   oraParameter.OracleDbType = TypeToDbType(clazzProperty.PropertyType.Name);

            }
            else
                oraParameter.OracleDbType = TypeToDbType(clazzProperty.PropertyType.Name);

            pInfo.DatabaseParameter = oraParameter;
            pInfo.DatabaseParameter.Size = DbTypeSize(clazzProperty.PropertyType.Name);
            
            return pInfo;
        }

   

        private static  OracleDbType TypeToDbType(string TypeName)
        {

            switch (TypeName)
            {
                case "Guid":
                    return OracleDbType.Raw;
                case "Int64":
                    return OracleDbType.Int64;
                case "UInt32":
                case "Int32":
                    return OracleDbType.Int32;
                case "Int16":
                    return OracleDbType.Int16;                
                case "String":
                    return OracleDbType.NVarchar2;
                case "Single":
                    return OracleDbType.Single;
                case "Decimal":
                    return OracleDbType.Decimal;
                case "Double":
                    return OracleDbType.Double;
                case "Char":
                    return OracleDbType.Char;
                case "Byte[]":
                    return OracleDbType.Blob;
                case "Byte":
                    return OracleDbType.Byte;
                case "DateTime":
                case "TimeSpan":
                    return OracleDbType.Date;
                default:
                    return OracleDbType.NVarchar2;
            }
        }

        private static  int DbTypeSize(string TypeName)
        {
            switch (TypeName)
            {
                case "Byte[]":
                    return 4000;
                case "Guid":
                    return 16;
                case "string":
                    return 4000;

                default:
                    return 0;

            }
        }





    }
}
